import { BlockVolume, Vector3, world } from "@minecraft/server";
import { Dimensions } from "@sapi-game/constants";
import { GameComponent } from "@sapi-game/gameComponent";
import { Game } from "@sapi-game/main";
import { Duration, RandomUtils, Vector3Utils } from "@sapi-game/utils";
import { BlockedMainState } from "../states/mainState";

export class BlockedInCombatSpawnPoint extends GameComponent<BlockedMainState> {
    override onAttach(): void {
        this.initSpawnPoint();
        this.setPlayerSpawnPoint();

        this.subscribe(
            Game.events.interval,
            () => {
                this.setPlayerSpawnPoint();
                this.protectSpawnArea();
            },
            new Duration(10)
        );
        const protectedSpawnPoints = this.context.teams
            .filter((team) => team.data.spawnPoint)
            .map((team) => Vector3Utils.below(team.data.spawnPoint!));
        //出生点保护
        this.subscribe(world.beforeEvents.playerInteractWithBlock, (t) => {
            const isProtected = protectedSpawnPoints.some((p) =>
                Vector3Utils.isEqual(t.block.location, p)
            );
            if (isProtected) {
                t.cancel = true;
            }
        });
    }

    private initSpawnPoint() {
        const teams = this.context.teams;
        const spawnPoints = RandomUtils.shuffle(this.context.map.spawnPoints);
        for (let i = 0; i < teams.length; i++) {
            if (teams[i].size == 0) continue;
            teams[i].data.spawnPoint = spawnPoints[i];
        }
    }

    setPlayerSpawnPoint() {
        this.context.teams.forEach((t) => {
            if (!t.data.spawnPoint) return;
            t.forEach((p) =>
                p.player.setSpawnPoint({
                    dimension: Dimensions.Overworld,
                    ...t.data.spawnPoint!,
                })
            );
        });
    }

    tpAllPlayersToSpawn() {
        this.context.teams.forEach((t) => {
            if (!t.data.spawnPoint) return;
            t.forEach((p) => p.player.teleport(t.data.spawnPoint!));
        });
    }

    resetAllSpawnAreas() {
        this.context.teams.forEach((t) => {
            if (t.data.spawnPoint) {
                this.resetSpawnArea(t.data.spawnPoint);
            }
        });
    }

    private resetSpawnArea(center: Vector3) {
        const max = Vector3Utils.add(center, { x: 1, y: 1, z: 1 });
        const min = Vector3Utils.subtract(center, { x: 1, y: 0, z: 1 });
        const dim = world.getDimension(this.context.map.region.dimensionId);
        dim.fillBlocks(new BlockVolume(max, min), "air");
        dim.setBlockType(Vector3Utils.below(center), "bedrock");
    }

    /**保护出生点(设为空气) */
    private protectSpawnArea() {
        this.context.teams.forEach((t) => {
            if (!t.data.spawnPoint) return;
            try {
                const dim = world.getDimension(
                    this.context.map.region.dimensionId
                );
                dim.setBlockType(t.data.spawnPoint, "air");
            } catch (err) {}
        });
    }
}
